<template>
  <el-dialog v-model="dialogFormVisible" width="60%" @close="close">
    <div>
      <div :id="mapId" class="map"></div>
    </div>
    <div style="margin: 0 auto; width: 280px" v-if="useButton">
      <el-button type="danger" @click="removeLayer">清 除</el-button>
      <el-button type="primary" @click="onAddInteraction('Polygon')">{{
        lineLayer !== null ? "重新绘制" : "绘 制"
      }}</el-button>
      <el-button type="primary" @click="onSubmit()"> 确 认 </el-button>
    </div>
  </el-dialog>
</template>
<script>
//导入基本模块
import "ol/ol.css";
import Map from "ol/Map";
import View from "ol/View";
import { Fill, Style, Stroke } from "ol/style";
//导入相关模块
import { Tile as TileLayer, Vector as VectorLayer } from "ol/layer";
import { TileWMS, Vector as VectorSource } from "ol/source";
import { Select, Draw } from "ol/interaction";
import { getArea } from "ol/sphere";
import { get as getProjection } from "ol/proj.js";
import { transform } from "ol/proj";
import { getWidth } from "ol/extent.js";
import TileGrid from "ol/tilegrid/TileGrid.js";
import Feature from "ol/Feature";
import { Polygon } from "ol/geom";
import { geoserver } from "@/api/common.js";
let points = [];
export default {
  name: "olMapTileWMSDrawPolygon",
  emits: ["change", "close"],
  props: {
    useButton: {
      type: Boolean,
      default: true,
    },
    mapId: {
      type: String,
      default: "map",
    },
  },
  data() {
    return {
      map: null, // map地图
      layer: null, //地图图层
      lineLayer: null, //线图层
      draw: null,
      lineSource: null,
      coordinate: [],
      dialogFormVisible: false,
      feature: null,
      points: [],
      mapUrl: null,
      epsg4326Coord: []
    };
  },
  created() {
    geoserver().then((res) => {
      this.mapUrl = res.data;
    });
  },
  methods: {
    // 绘图工具
    onAddInteraction(type) {
      this.removeLayer();
      let self = this;
      //线的图层
      this.lineSource = new VectorSource({ wrapX: false });
      this.lineLayer = new VectorLayer({
        source: this.lineSource,
      });
      this.map.addLayer(this.lineLayer);
      // 获取点击地图的坐标(选中样式)
      let selectedStyle = new Style({
        fill: new Fill({
          color: "rgba(255, 0, 0, 0.5)",
        }),
        stroke: new Stroke({
          color: "yellow",
          width: 1.5,
        }),
      });
      // 选择线的工具类
      this.selectTool = new Select({
        multi: true,
        hitTolerance: 10, // 误差
        style: selectedStyle, // 选中要素的样式
      });
      //添加交互
      this.map.addInteraction(this.selectTool);
      //勾绘矢量图形的类
      this.draw = new Draw({
        //source代表勾绘的要素属于的数据集
        source: self.lineSource,
        //type 表示勾绘的要素包含的 geometry 类型
        type: type,
      });
      //绘制结束时触发的事件
      this.draw.on("drawend", function (e) {
        const geometry = e.feature.getGeometry();

        var area = getArea(geometry);
        // console.log("area=" + area);
        var output;
        if (area > 10000) {
          output =
            Math.round((area / 1000000) * 100) / 100 + " " + "km<sup>2</sup>";
        } else {
          output = Math.round(area * 100) / 100 + " " + "m<sup>2</sup>";
        }
        let pointArr = geometry.getCoordinates();
        points = JSON.parse(JSON.stringify(pointArr));
        self.coordinate.push(pointArr);
        self.removeDraw();
      });
      self.map.addInteraction(this.draw);
    },
    //删除交互
    removeDraw() {
      this.map.removeInteraction(this.draw);
    },
    removeLayer() {
      this.map.removeLayer(this.lineLayer);
      this.lineLayer = null;
      points = [];
      this.$emit("change", []);
      this.removeDraw();
    },
    async initMap(data) {
      await geoserver().then((res) => {
        this.mapUrl = res.data;
      });
      const projExtent = getProjection("EPSG:3857").getExtent();
      const startResolution = getWidth(projExtent) / 256;
      const resolutions = new Array(22);
      for (let i = 0, ii = resolutions.length; i < ii; ++i) {
        resolutions[i] = startResolution / Math.pow(2, i);
      }
      const tileGrid = new TileGrid({
        extent: [
          13512793.694715144, 3692705.0036003077, 13515852.525118226,
          3696369.8737244364,
        ],
        resolutions: resolutions,
        tileSize: [642, 768],
      });

      //地图图层
      this.layer = new TileLayer({
        source: new TileWMS({
          url:
            this.mapUrl ||
            import.meta.env.VITE_APP_BASE_MAPURL + "/geoserver/wms",
          crossOrigin: "anonymous",
          params: {
            LAYERS: "grotto:L17",
            TILED: true,
            format: "image/png",
          },
          serverType: "geoserver",
          tileGrid: tileGrid,
        }),
      });

      const layers = [this.layer];
      if (data && data.length) {
        this.lineSource = new VectorSource({ wrapX: false });
        this.lineLayer = new VectorLayer({
          source: this.lineSource,
        });
        this.drawPolygon(data);
        layers.push(this.lineLayer);
      }
      this.map = new Map({
        //地图容器ID
        target: this.mapId,
        //引入地图
        layers,
        view: new View({
          // center: [-10997148, 4569099],
          center: [13514313.694715144, 3694580.0036003077],
          zoom: 15,
          minZoom: 10,
          maxZoom: 18,
        }),
      });

      // this.map.on('singleclick', function(evt) {
      //   this.epsg4326Coord = transform(evt.coordinate,'EPSG:3857', 'EPSG:4326')
      //   console.log('epsg4326Coord: ', this.epsg4326Coord)
      // });

      //调用绘图工具并传递类型为线，其他类型有Point,LineString,Polygon,Circle
      // this.onAddInteraction("Polygon");
    },
    reSetPoints(data) {
      this.map.removeLayer(this.lineLayer);
      this.lineLayer = null;
      if (!data || data.length == 0) return;
      this.setLineLayer(data);
    },
    setLineLayer(data) {
      this.lineSource = new VectorSource({ wrapX: false });
      this.lineLayer = new VectorLayer({
        source: this.lineSource,
      });
      this.map.addLayer(this.lineLayer);
      this.drawPolygon(data);
    },
    drawPolygon(data) {
      let self = this;
      var feature = new Feature({
        type: "Polygon",
        geometry: new Polygon(
          data // 线的坐标
        ),
      });
      let lineStyle = new Style({
        fill: new Fill({
          color: "rgba(255, 0, 0, 0.5)",
        }),
        stroke: new Stroke({
          color: "rgba(255, 0, 0, 0.5)",
          width: 1,
        }),
      });

      // 添加线的样式
      feature.setStyle(lineStyle);
      this.feature = feature;
      // 添加线的fature
      self.lineSource.addFeature(feature);
    },
    open(data) {
      this.dialogFormVisible = true;
      points = data || [];

      this.$nextTick().then(() => {
        if (this.map === null) {
          this.initMap(data);
        } else {
          this.reSetPoints(data);
        }
      });
    },
    close() {
      this.dialogFormVisible = false;
      this.$emit("close");
    },
    onSubmit() {
      let data = {
        points,
        epsg4326Coord: points.length > 0 ? transform(points[0][0],'EPSG:3857', 'EPSG:4326') : []
      }
      this.$emit("change", data);
      this.close();
    },
  },
};
</script>

<style scoped>
.map {
  width: 100%;
  height: 700px;
}
</style>